package com.service.business.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.service.business.base.dto.LoginUserSession;
import com.service.business.merchant.controller.rep.CommodityDetailRep;
import com.service.business.merchant.controller.rep.CommodityPageRep;
import com.service.business.merchant.controller.req.CommoditySaveReq;
import com.service.business.merchant.controller.req.CommodityUpdateReq;
import com.service.business.merchant.service.MerchantCommodityPriceService;
import com.service.business.merchant.service.MerchantCommodityService;
import com.service.business.merchant.service.MerchantService;
import com.service.business.support.Language;
import com.service.business.support.SessionUtil;
import com.service.business.utils.I18nUtil;
import com.service.business.utils.LanguageUtil;
import com.service.core.exception.CommonException;
import com.service.core.rest.request.PageRequest;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.enums.CommonStatusEnums;
import com.service.dao.enums.MerchantCommodityEnum;
import com.service.dao.mapper.MerchantCommodityMapper;
import com.service.dao.model.Merchant;
import com.service.dao.model.MerchantCommodity;
import com.service.dao.model.MerchantCommodityPrice;
import com.service.utility.common.UUIDUtil;
import com.service.utility.modelmapper.ModelMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service("merchantCommodityService")
public class MerchantCommodityServiceImpl extends ServiceImpl<MerchantCommodityMapper, MerchantCommodity> implements MerchantCommodityService {

    @Autowired
    private MerchantCommodityPriceService commodityPriceService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private SessionUtil sessionUtil;

    @Value("${merchantCommodityPrefix}")
    private String merchantCommodityPrefix;

    @Override
    public CommonPageRep<CommodityPageRep> page(String merchantNo, PageRequest pageRequest) {
        LoginUserSession session = sessionUtil.getUser();

        Merchant merchant = StringUtils.isBlank(merchantNo)
                ? merchantService.getByMemberIdAndStatus(session.getUserId()) : merchantService.getByMerchantNo(merchantNo);
        if (ObjectUtils.isEmpty(merchant)) {
            throw new CommonException("暂未开通商家服务", "merchant_exception_not_service");
        }
        String language = Language.LANG.get();
        Page<MerchantCommodity> page = PageHelper.startPage(pageRequest.getPageNo(), pageRequest.getPageSize());
        LambdaQueryWrapper<MerchantCommodity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MerchantCommodity::getMerchantId, merchant.getId());

        if (StringUtils.isNoneBlank(merchantNo)) {
            queryWrapper.eq(MerchantCommodity::getProductStatus, MerchantCommodityEnum.Status.PUT_AWAY.getCode());
        } else {
            queryWrapper.in(MerchantCommodity::getProductStatus, MerchantCommodityEnum.listUseStatus());
        }

        list(queryWrapper);

        return CommonPageRep.buildResultRep(page, page.getResult().stream().map(item -> {
            CommodityPageRep result = ModelMapperUtil.map(item, CommodityPageRep.class);
            MerchantCommodityPrice price = commodityPriceService.getCommodityPrice(item.getId(), language);
            if (!ObjectUtils.isEmpty(price)) {
                result.setPrice(price.getPrice());
                result.setUnit(price.getCoinsName());
            }
            if (StringUtils.isNotBlank(merchantNo)) {
                result.setProductStatus(null);
            }
            return result;
        }).collect(Collectors.toList()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addCommodity(CommoditySaveReq saveReq) {

        LoginUserSession session = sessionUtil.getUser();
        Merchant merchant = merchantService.getByMemberIdAndStatus(session.getUserId());
        MerchantCommodity commodity = ModelMapperUtil.map(saveReq, MerchantCommodity.class);

        commodity.setCreateUserId(session.getUserId());
        commodity.setCreateLoginName(session.getAccount());
        commodity.setCreateUserName(session.getUsername());
        commodity.setCreateTime(new Date());
        commodity.setCommodityNo(this.buildMerchantCommodityNo());
        commodity.setMerchantId(merchant.getId());

        save(commodity);

        commodityPriceService.saveCommodityPrice(commodity.getId(), saveReq.getPriceList());

    }

    public String buildMerchantCommodityNo() {
        String no = merchantCommodityPrefix + DateFormatUtils.format(new Date(), "yyyyMMdd") + UUIDUtil.randomUUID10().substring(0, 8);
        MerchantCommodity commodity = getByCommodityNo(no);
        if (!ObjectUtils.isEmpty(commodity)) {
            no = buildMerchantCommodityNo();
        }
        return no;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCommodity(String commodityNo, CommodityUpdateReq updateReq) {
        LoginUserSession session = sessionUtil.getUser();
        Merchant merchant = merchantService.getByMemberIdAndStatus(session.getUserId());
        MerchantCommodity commodity = getByCommodityNo(commodityNo);
        if (ObjectUtils.isEmpty(commodity)) {
            throw new CommonException("该商品不存在", "merchant_commodity_exception_not_exist");
        }

        if(!ObjectUtils.nullSafeEquals(merchant.getId(), commodity.getMerchantId())){
            throw new CommonException("该商品不存在", "merchant_commodity_exception_not_exist");
        }

        Integer id = commodity.getId();
        commodity = ModelMapperUtil.map(updateReq, MerchantCommodity.class);
        commodity.setId(id);
        updateById(commodity);

        if (ObjectUtils.isEmpty(updateReq.getPriceList())) {
            return;
        }
        commodityPriceService.updateCommodityPrice(commodity.getId(), updateReq.getPriceList());
    }

    @Override
    public CommodityDetailRep detail(String commodityNo) {
        LoginUserSession session = sessionUtil.getUser();

        MerchantCommodity commodity = getByCommodityNo(commodityNo);
        if (ObjectUtils.isEmpty(commodity)) {
            throw new CommonException("该商品不存在", "merchant_commodity_exception_not_exist");
        }
        Merchant merchant = merchantService.getById(commodity.getMerchantId());

        CommodityDetailRep result = ModelMapperUtil.map(commodity, CommodityDetailRep.class);
        String language = Language.LANG.get();
        if (ObjectUtils.nullSafeEquals(merchant.getMemberId(), session.getUserId())) {
            result.setProductStatus(commodity.getProductStatus());
            result.setLanguagePrice(commodityPriceService.getCommodityPrice2List(commodity.getId()));
        } else {
            if (!ObjectUtils.nullSafeEquals(commodity.getProductStatus(), MerchantCommodityEnum.Status.PUT_AWAY.getCode())) {
                throw new CommonException("该商品已下架", "merchant_commodity_exception_has_take_off");
            }
            MerchantCommodityPrice price = commodityPriceService.getCommodityPrice(commodity.getId(), language);
            if (!ObjectUtils.isEmpty(price)) {
                result.setPrice(price.getPrice());
                result.setUnit(price.getCoinsName());
            }
        }
        return result;
    }

    @Override
    public MerchantCommodity getByCommodityNo(String commodityNo) {
        return getOne(new QueryWrapper<MerchantCommodity>().lambda()
                .eq(MerchantCommodity::getCommodityNo, commodityNo).last("limit 1"));
    }

    @Override
    public MerchantCommodity getByCommodityNoAndStatus(String commodityNo) {

        MerchantCommodity commodity = getOne(new QueryWrapper<MerchantCommodity>().lambda()
                .eq(MerchantCommodity::getCommodityNo, commodityNo)
                .eq(MerchantCommodity::getProductStatus, MerchantCommodityEnum.Status.PUT_AWAY.getCode())
                .last("limit 1"));

        if(ObjectUtils.isEmpty(commodity)){
            String msg = I18nUtil.getMessage("merchant_commodity_exception_commodity_no_not_exist", Language.LANG.get(), commodityNo);
            log.error("商品编号<{}>的商品不存在或已下架", commodityNo);
            throw new CommonException(msg);
        }

        return commodity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(String commodityNo, MerchantCommodityEnum.Status status) {
        MerchantCommodity commodity = getByCommodityNo(commodityNo);
        if (ObjectUtils.isEmpty(commodity)) {
            throw new CommonException("该商品不存在", "merchant_commodity_exception_not_exist");
        }
        updateById(MerchantCommodity.builder().id(commodity.getId()).productStatus(status.getCode()).build());
    }
}
